只有一个公网IP也可以使用LVS的DR模式!(外带php session粘滞问题解决)

        单个公网ip怎么才能使用LVS的DR模式?倒不是因为没有公网IP,而是由于安全性的考虑不希望服务器都暴漏在外,又不想因为这个小项目买防火墙,所以就提了这个要求。

        怎么样才能实现呢?一个公网IP也可以做DR啊,前面加个路由器就可以了

        具体结构就想上面那个图那样

        原理就是让 路由器把所有的80端口请求都分给VIP,分发器再分给每个web服务器,而web服务器处理完请求后跟客户连接就不走分发器了,直接通过路由器去外网了,这样就实现了只用一个公网IP也能用DR模式,呵呵 具体配置如下

        先从内网找了三台服务器分别是:

  • 192.168.1.166 web1
  • 192.168.1.167 web2
  • 192.168.1.160 分发器
  • 192.168.1.169 VIP

        192.168.1.1 路由器内网ip(网关) 路由器是随便找的一台tplink adal路由器,凑合着测试用的

        211.83.113.119 路由器的WAN口IP

        先安装ipvsadm 直接yum install ipvsadm就行了

        用的是keepalived,配置文件贴上来,以下是分发器上的设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
global_defs {
notification_email {
ufo@xman.com
}
notification_email_from Alexandre.Cassen@firewall.loc
smtp_server smtp.qq.com
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_sync_group VG1 {
group{
VI_1
}
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 33210
}
virtual_ipaddress {
192.168.1.169
}
virtual_server 192.168.1.169 80 {
delay_loop 6
lb_algo rr
lb_kind DR
protocol TCP
real_server 192.168.1.166 80 {
weight 1
inhibit_on_failure
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.1.167 80 {
weight 1
inhibit_on_failure
TCP_CHECK {
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}

        配置文件写完了,然后就是

1
2
3
4
5
mkdir /etc/keepalived #系统默认会到这里去找配置文件
cp /usr/local/keepalive/etc/keepalived/keepalived.conf /etc/keepalived/
cp /usr/local/keepalive/etc/rc.d/init.d/keepalived /etc/init.d/
cp /usr/local/keepalive/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalive/sbin/keepalived /bin/ #将可执行程序放入sbin 或者 bin目录里
1
2
3
vim /etc/sysctl.conf
net.ipv4.ip_forward = 1

        保存退出 后执行

1
sysctl -p

        route add defaule gw 192.168.1.1 把路由内网地址添加为默认网关

        web服务器设置

        两台web服务器也要修改 /etc/sysctl.conf 修改内容如下

1
2
3
4
5
6
7
vim /etc/sysctl.conf
# LVS
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
sysctl -p

        之后还要增加vip

        ifconfig lo:1 192.168.1.169 netmask 255.255.255.255 别忘了加到rc.local里面

        route add defaule gw 192.168.1.1 把路由内网地址添加为默认网关

        路由器设置

        路由器的设置没什么好说的,除了上网设置以外还要做一个端口映射,就是把80端口映射到 vip上也就是192.168.1.169

        现在启动keepalived吧

1
/etc/init.d/keepalived start

        开始的时候比较慢,大概1分钟后系统日志里面出现下面这条记录就OK了

1
avahi-daemon[3012]: Registering new address record for 192.168.1.169 on eth0

        访问一下 http://211.83.113.119 成功了

1
2
3
4
5
6
7
ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.169:80 rr
-> 192.168.1.166:80 Route 1 5 6
-> 192.168.1.167:80 Route 1 3 9

        后来遇到了一个问题,由于这套应用处在一个大网站的后台,所以大部分的请求都来自同一个IP地址,而有一部分程序需要给每个连接做session粘滞,

        这样就不能用lvs 的-p参数来设置ip粘滞时间,如果用lvs的粘滞时间的话大部分的请求都将分给同一台web服务器(注意:这里是session粘滞而不是IP粘滞),

        lvs可做不到这点,怎么办呢?

        解决办法是 将session共享,共享到什么地方就有很多选择了

        这里是把所有web服务器的php session都给memcached ,这样不管分发器把 ip连接分给哪个web服务器都不会有问题了,配置方法很简单,就在php的配置文件内

        增加一条语句就可以了,不过前提需要装好memcache模块

1
2
3
4
[Session]
; Handler used to store/retrieve data.
session.save_handler = memcache
session.save_path = "tcp://192.168.1.161:11213"